package io.api.modules.project.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import io.admin.common.constant.Constant;
import io.admin.common.page.PageData;
import io.admin.common.service.impl.CrudServiceImpl;
import io.admin.common.utils.ConvertUtils;
import io.api.modules.project.dao.AnchorDao;

import io.api.modules.project.dto.AnchorDTO;
import io.api.modules.project.dto.PageAnchorDTO;
import io.api.modules.project.entity.AnchorEntity;

import io.api.modules.project.entity.FileUrlEntity;
import io.api.modules.project.service.AnchorService;
import io.api.modules.project.service.FileUrlService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户
 *
 * @author Mark sunlightcs@gmail.com
 * @since 1.0.0 2024-07-09
 */
@Service
public class AnchorServiceImpl extends CrudServiceImpl<AnchorDao, AnchorEntity, AnchorDTO> implements AnchorService {

    @Autowired
    private FileUrlService fileUrlService;

    @Override
    public QueryWrapper<AnchorEntity> getWrapper(Map<String, Object> params) {
        String name = (String)params.get("name");

        Long lineId = (Long) params.get("lineId");
        Long projectId = (Long) params.get("projectId");

        QueryWrapper<AnchorEntity> wrapper = new QueryWrapper<>();
        wrapper.like(StrUtil.isNotBlank(name), "name", name);

        wrapper.eq(Objects.nonNull(lineId), "line_id", lineId);
        wrapper.eq(Objects.nonNull(projectId), "project_id", projectId);
        wrapper.orderByAsc("sort");
        return wrapper;
    }

    @Override
    public PageData<PageAnchorDTO> pageAnchors(Map<String, Object> params) {
        //分页
        IPage<AnchorEntity> page = getPage(params, "sort", true);
        //查询
        List<AnchorEntity> list = baseDao.getList(params);
        return getPageData(list, page.getTotal(), PageAnchorDTO.class);
    }

    /**
     * 创建定位点
     * @param dto
     */
    @Transactional
    @Override
    public AnchorEntity insert(AnchorDTO dto) {

        AnchorEntity lastOne = baseDao.selectOne(new LambdaQueryWrapper<AnchorEntity>()
                        .eq(Objects.nonNull(dto.getLineId()), AnchorEntity::getLineId, dto.getLineId())
                        .orderByDesc(AnchorEntity::getSort)
                        .last("limit 1"));
        if (Objects.isNull(lastOne)) {
            dto.setSort(1);
        } else {
            dto.setSort(lastOne.getSort() + 1);
        }
        AnchorEntity anchorEntity = ConvertUtils.sourceToTarget(dto, AnchorEntity.class);
        // 保存定位点
        baseDao.insert(anchorEntity);

        anchorFiles(dto, anchorEntity.getId());
        return anchorEntity;
    }

    @Override
    public int countByNameAndLineId(String name, Long lineId, Long anchorId) {
        return baseDao.countByNameAndLineId(name, lineId, anchorId);
    }

    @Override
    public int countByLineId(Long lineId) {
        return baseDao.countByLineId(lineId);
    }

    @Override
    public void update(AnchorDTO dto) {
        Long[] imageIDs = fileUrlService.selectByKeysId(dto.getId())
                .stream().map(FileUrlEntity::getId).toArray(Long[]::new);

        if (imageIDs.length > 0) {
//            fileUrlService.delete(imageIDs);
            List<Long> newImageIds = Arrays.asList(dto.getImageIds());
            Long[] ids = Arrays.stream(imageIDs).filter(id -> !newImageIds.contains(id)).toArray(Long[]::new);
            fileUrlService.delete(ids);
        }
        anchorFiles(dto, dto.getId());
        super.update(dto);
    }

    @Override
    public AnchorDTO get(Long id) {
        AnchorEntity entity = baseDao.getById(id);
        AnchorDTO anchorDTO = ConvertUtils.sourceToTarget(entity, AnchorDTO.class);
        List<FileUrlEntity> list = fileUrlService.selectByKeysId(id);
        if (!list.isEmpty()) {
            anchorDTO.setImageIds(list.stream().map(FileUrlEntity::getId).toArray(Long[]::new));
        }
        return anchorDTO;
    }

    @Override
    public boolean deleteById(Serializable id) {
        fileUrlService.deleteByKeysId((Long) id);
        return super.deleteById(id);
    }

    @Override
    public List<AnchorDTO> list(Long lineId) {
        Map<String, Object> params = new HashMap<>();
        params.put("lineId", lineId);
        List<AnchorEntity> list = baseDao.getList(params);
        return ConvertUtils.sourceToTarget(list, AnchorDTO.class);
    }

    @Override
    public List<AnchorDTO> listByProjectId(Long projectId) {
        Map<String, Object> params = new HashMap<>();
        params.put("projectId", projectId);
        List<AnchorEntity> list = baseDao.getList(params);
        return ConvertUtils.sourceToTarget(list, AnchorDTO.class);
    }

    private void anchorFiles(AnchorDTO dto, Long id) {
        if (dto.getImageIds().length > 0) {
            List<FileUrlEntity> fileUrlEntities = Arrays.stream(dto.getImageIds()).map(fileId -> {
                FileUrlEntity fileUrlEntity = new FileUrlEntity();
                fileUrlEntity.setId(fileId);
                fileUrlEntity.setKeysId(id);
                return fileUrlEntity;
            }).collect(Collectors.toList());
            fileUrlService.updateBatchById(fileUrlEntities);
        }
    }

}